/*
 * SpeedoDyno - Speedometer and dynamometer application for Android 
 * Copyright 2013 Guilhem VALENTIN
 * 
 * This file is part of SpeedoDyno
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with SpeedoDyno. If not, see <http://www.gnu.org/licenses/>.
 */
package com.gvalentin.speedodyno.util;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/**
 * List of elements with fixed capacity.
 * When max capacity is reached and a new element is added,
 * the older element is removed.
 * @author guilhem
 */
public class CapacityRollingList<T> implements RollingList<T> {
	
	protected int capacity;
	protected List<T> items;
	
	/**
	 * Constructor
	 * @param initialCapacity
	 */
	public CapacityRollingList(int capacity) {
		this.capacity = capacity;
		this.items = new ArrayList<T>(capacity);
	}
	
	/**
	 * Add item at last position in the list
	 * @param item
	 */
	public boolean add(T item) {
        while (items.size() > capacity - 1) {
    		try {
    			removeHint(0, items.get(0));
    		} catch (Exception e) { }
            items.remove(0);
        }
        
        return items.add(item);
	}
	
	/**
	 * Callback called when item 
	 * @param index index being removed
	 */
	protected void removeHint(int index, T item) {
	}
	
	/**
	 * Gets current size of the list
	 * @return
	 */
	public int size() {
		return items.size();
	}
	
	/**
	 * Indicate whether list is empty
	 * @return
	 */
	public boolean isEmpty() {
		return items.isEmpty();
	}
	
	/**
	 * Indicate whether list is full
	 * @return
	 */
	public boolean isFull() {
		return (items.size() == capacity);
	}
	
    /**
     * Retrieves the item at the specified index in this list.
     * @param index The index to look up
     * @return The item at the specified index
     */
    public T get(final int index) {
        return items.get(index);
    }
    
	/**
     * Retrieves the last item in this list.
     * @param index The index to look up
     * @return The item at the last index
	 */
	public T getLast() {
		if (!items.isEmpty()) {
			return items.get(items.size()-1);
		} else {
			return null;
		}
	}
	
	/**
	 * Get iterator on list
	 */
	public Iterator<T> iterator() {
		return items.iterator();
	}
	
	/**
	 * Get list iterator on list
	 */
	public ListIterator<T> listIterator() {
		return items.listIterator();
	}
}
